<?php
/**
 * 此类是支付回调处理业务逻辑的
 * **/
namespace app\client\lib;
use app\common\lib\Redis;
use think\swoole\facade\Task;
use app\common\lib\InnerCurl;

class PayHandle {
    
    const CHATEXPIRE = 100 * 24 * 3600;
    
    /**
     * LBS红包
     * **/
    public static function lbsChatRedenvelope($data, &$msg, $payType = 0) {
        $orderNo = $data['out_trade_no'];
        $openid = '';
        $tradeNo = '';
        $totalFee = 0;
        
        if($payType == 0){ //微信支付
            $openid = $data['openid'];
            $tradeNo = $data['transaction_id'];
            $totalFee = $data['total_fee'];
        }else if($payType == 1){ //支付宝支付
            $openid = $data['buyer_id'];
            $tradeNo = $data['trade_no'];
        }
        
        $redis = new Redis();
        
        //查出chat数据
        $chatData = $redis->get('redenvelope_' . $orderNo);
        $redis->close();
        
        if(!$chatData){
            $msg = 'chat缓存数据丢失';
            return false;
        }
        
        $chatData = json_decode($chatData, true);
        
        if(!$chatData){
            $msg = 'chat缓存数据丢失1';
            return true;
        }
        
        $orderModel = model('ChatRedenvelopeOrder'); //红包支付订单
        
        //查出红包订单
        $order = $orderModel->findOne(['order_no' => $orderNo], ['amount', 'order_id', 'user_id', 'status']);
        if(!$order){
            $msg = '订单不存在';
            return true;
        }
        
        if($order['status'] != 0){
            $msg = '订单已完成';
            return true;
        }
        
        /* if(intval($order['amount'] * 100) !== $totalFee){
            $msg = '金额不符';
            return true;
        } */
        
        if($order['user_id'] != $chatData[0]['user_id']){
            $msg = '用户不符';
            return true;
        }
        
        $time = time();
        
        $orderModel->startTrans();
        
        try {
            //说说入库
            $chatId = model('Chat')->add($chatData[0]);
            if(!$chatId){
                $orderModel->rollback();
                $msg = 'chat表入库失败';
                return false;
            }
            
            
            //红包信息入库
            $chatData[1]['chat_id'] = $chatId;
            $chatRedenvelopeId = model('ChatRedenvelope')->add($chatData[1]);  //加入红包表
            if(!$chatRedenvelopeId){
                $orderModel->rollback();
                $msg = 'chat_redenvelope表入库失败';
                return false;
            }
            
            //更新订单信息
            $result = $orderModel->modify(['order_id' => $order['order_id']], ['trade_no' => $tradeNo, 'chat_redenvelope_id' => $chatRedenvelopeId, 'pay_time' => $time, 'status' => 1]);
            if(!$result){
                $orderModel->rollback();
                $msg = '更新订单信息失败';
                return false;
            }
            
            $result = model('RedenvelopeLog')->add(['chat_id' => $chatId, 'user_id' => $order['user_id'], 'type' => 1, 'cover' => isset($chatData[0]['cover']) ? $chatData[0]['cover'] : '', 'content' => isset($chatData[0]['content']) ? substr($chatData[0]['content'], 0, 30) : '', 'amount' => $order['amount'], 'add_time' => $time]);
            if(!$result){
                $orderModel->rollback();
                $msg = '加入红包记录';
                return false;
            }
            
            
            $amount = $order['amount'];
            $quantity = $chatData[1]['quantity'];
            $CHATEXPIRE = self::CHATEXPIRE;
            
            Task::async(function() use($chatId, $chatRedenvelopeId, $chatData, $CHATEXPIRE, $orderNo, $amount, $quantity){
                $userId = $chatData[0]['user_id'];
                $redis = new Redis();
                try {
                    $chatType = $chatData[1]['type'];
                    $redData = $chatId . ',' .$chatRedenvelopeId . ',' . $userId;
                    if($chatType == 1){ //如果是LBS红包，地理位置入redis
                        $redis->geoadd('near_redenvelope', $chatData[0]['longitude'], $chatData[0]['latitude'], $redData);
                    }elseif ($chatType == 2){ //城市红包
                        $redis->sAdd('redenvelope_city_' . $chatData[1]['city_id'], $redData);
                    }else { //全国红包
                        $redis->sAdd('redenvelope_country', $redData);
                    }
                    
                    $redis->setex('chat_' . $chatId, array_merge($chatData[0], $chatData[1]), $CHATEXPIRE);
                    
                    unset($chatData);
                    
                    
                    $balance = roundNumber($amount - roundNumber((0.01 * $quantity), 2), 2); //保证每个人能最低收到0.01元
                    $listKey = 'redenvelope__list_' . $chatId;
                    //生成红包分配缓存队列
                    for($i = 0; $i < $quantity; $i ++) {
                        $luckMoney = roundNumber($amount / $quantity);
                        $redis->lpush($listKey, $luckMoney);
                    }
                } catch (\Exception $e) {
                    
                }
                
                try {
                    $key = redisUserKey($userId);
                    $user = $redis->get($key);
                    if(!empty($user)) {
                        $user = json_decode($user, true);
                        $user['chat_number'] += 1;
                        $redis->set($key, $user);
                    }
                } catch (\Exception $e) {
                }
                
                $redis->close();
                
                InnerCurl::reward('invite', ['id' => $userId]);
                
                return true;
            });
            
            $orderModel->commit();
            
            return true;
        
        } catch (\Exception $e) {
            $orderModel->rollback();
            $msg = $e->getMessage();
            return false;
        }
        
    }
    
    //产品红包
    public static function goodsRedenvelopeNotify($data, &$msg, $payType = 0) {
        $orderNo = $data['out_trade_no'];
        $openid = '';
        $tradeNo = '';
        $totalFee = 0;
        
        if($payType == 0){ //微信支付
            $openid = $data['openid'];
            $tradeNo = $data['transaction_id'];
            $totalFee = $data['total_fee'];
        }else if($payType == 1){ //支付宝支付
            $openid = $data['buyer_id'];
            $tradeNo = $data['trade_no'];
        }
        
        $redis = new Redis();
        
        
        //查出chat数据
        $chatData = $redis->get('goods_redenvelope_' . $orderNo);
        $redis->close();
        
        if(!$chatData){
            $msg = 'chat缓存数据丢失';
            return false;
        }
        
        $chatData = json_decode($chatData, true);
        if(!$chatData){
            $msg = 'chat缓存数据丢失1';
            return true;
        }
        
        $orderModel = model('GoodsRedenvelopeOrder');
        
        //查出红包订单
        $order = $orderModel->findOne(['order_no' => $orderNo], ['amount', 'order_id', 'user_id', 'status']);
        if(!$order){
            $msg = '订单不存在';
            return true;
        }
        
        if($order['status'] != 0){
            $msg = '订单已完成';
            return true;
        }
        
        /* if(intval($order['amount'] * 100) !== $totalFee){
            $msg = '金额不符';
            return true;
        } */
        
        if($order['user_id'] != $chatData[0]['user_id']){
            $msg = '用户不符';
            return true;
        }
        
        $time = time();
        
        $orderModel->startTrans();
        
        try {
            //说说入库
            $chatId = model('Chat')->add($chatData[0]);
            if(!$chatId){
                $orderModel->rollback();
                $msg = 'chat表入库失败';
                return false;
            }
            
            
            //ChatGood表
            $chatData[1]['chat_id'] = $chatId;
            $chatGoodsId = model('ChatGoods')->add($chatData[1]);
            if(!$chatGoodsId){
                $orderModel->rollback();
                $msg = 'chat_goods表入库失败';
                return false;
            }
            
            
            //GoodsRedenvelope表
            $result = model('GoodsRedenvelope')->add(array_merge(['chat_id' => $chatId, 'user_id' => $order['user_id'], $chatData[2]]));
            if(!$result){
                $orderModel->rollback();
                $msg = 'GoodsRedenvelope表入库失败';
                return false;
            }
            
            //更新订单信息
            $result = $orderModel->modify(['order_id' => $order['order_id']], ['trade_no' => $tradeNo, 'chat_id' => $chatId, 'pay_time' => $time, 'status' => 1]);
            if(!$result){
                $orderModel->rollback();
                $msg = '更新订单信息失败';
                return false;
            }
            
            $result = model('RedenvelopeLog')->add(['chat_id' => $chatId, 'user_id' => $order['user_id'], 'type' => 2, 'cover' => isset($chatData[0]['cover']) ? $chatData[0]['cover'] : '', 'content' => isset($chatData[0]['content']) ? substr($chatData[0]['content'], 0, 30) : '', 'amount' => $order['amount'], 'add_time' => $time]);
            if(!$result){
                $orderModel->rollback();
                $msg = '加入红包记录';
                return false;
            }
            
            $amount = $order['amount'];
            $quantity = $chatData[2]['quantity'];
            $CHATEXPIRE = self::CHATEXPIRE;
            
            Task::async(function() use($chatId, $CHATEXPIRE, $chatData, $orderNo, $amount, $quantity) {
                 $redis = new Redis();
                 
                 try {
                     $redis->setex('chat_' . $chatId, array_merge($chatData[0], $chatData[1]), $CHATEXPIRE);
                     
                     unset($chatData);
                     
                     $balance = roundNumber($amount - roundNumber((0.01 * $quantity), 2), 2); //保证每个人能最低收到0.01元
                     $listKey = 'goods_redenvelope__list_' . $chatId;
                     //生成红包分配缓存队列
                     for($i = 0; $i < $quantity ; $i ++) {
                         $luckMoney = roundNumber($amount / $quantity);
                         $redis->lpush($listKey, $luckMoney);
                     }
                 } catch (\Exception $e) {
                 }
                 
                 try {
                     $key = redisUserKey($chatData[0]['user_id']);
                     $user = $redis->get($key);
                     if(!empty($user)) {
                         $user = json_decode($user, true);
                         $user['chat_number'] += 1;
                         $redis->set($key, $user);
                     }
                 } catch (\Exception $e) {
                 }
                 
                 
                 $redis->close();
                 
                 return true;
             });
            
            $orderModel->commit();
            
            return true;
            
        } catch (\Exception $e) {
            $orderModel->rollback();
            $msg = $e->getMessage();
            return false;
        }
    }
    
    public static function merchatapplyNotify($data, &$msg, $payType = 0) {
        $orderNo = $data['out_trade_no'];
        $openid = '';
        $tradeNo = '';
        $totalFee = 0;
        
        if($payType == 0){ //微信支付
            $openid = $data['openid'];
            $tradeNo = $data['transaction_id'];
            $totalFee = $data['total_fee'];
        }else if($payType == 1){ //支付宝支付
            $openid = $data['buyer_id'];
            $tradeNo = $data['trade_no'];
        }
        
        $redis = new Redis();
        $model = model('ApplyMerchant');
        $apply = $model->findOne(['order_no' => $orderNo], ['status', 'amount','id', 'user_id']);
        
        if($apply['status'] != 0){
            $msg = '订单已完成';
            return true;
        }
        
        /* if(intval($apply['amount'] * 100) !== $totalFee){
         $msg = '金额不符';
         return true;
         } */
        
        $time = time();
        
        $userModel = model('User');
        $user = $userModel->findOne(['user_id' => $apply['user_id']], ['inviter', 'merchant_begin']);
        $inviter = $user['inviter'];
        $expire = date('Y-m-d 00:00:00', $time);
        $expire = strtotime($expire);
        $expire = strtotime('+ 1 year', $expire);
        
        $model->startTrans();
        
        try {
            $rs = $model->modify(['id' => $apply['id']], ['trade_no' => $tradeNo, 'status' => 1]);
            if(!$rs){
                $model->rollback();
                $msg = '更新订单信息失败';
                return false;
            }
            
            $updateData = ['user_type' => 2, 'merchant_annual_expire' => $expire];
            if(empty($user['merchant_begin'])) {
                $updateData['merchant_begin'] = $time;
            }
            
            $rs = $userModel->modify(['user_id' => $apply['user_id']], $updateData);
            if(!$rs){
                $model->rollback();
                $msg = '更新User信息失败';
                return false;
            }
            
            try {
                $user = $redis->get('user_' . $apply['user_id']);
                $user = json_decode($user, true);
                $user['user_type'] = 2;
                $user['merchant_annual_expire'] = $expire;
                
                $redis->set('user_' . $apply['user_id'], $user);
                
                if($inviter > 0) {
                    Task::async(function() use($apply) {
                        InnerCurl::reward('invite', ['id' => $apply['user_id'], 'type' => 2]);
                    });
                }
                
                
            } catch (\Exception $e) {
            }
            $model->commit();
            $redis->close();
        } catch (\Exception $e) {
            $model->rollback();
            $redis->close();
            return false;
        }
        
        return true;
    }
    
    public static function agentApplyNotify($data, &$msg, $payType = 0) {
        $orderNo = $data['out_trade_no'];
        $openid = '';
        $tradeNo = '';
        $totalFee = 0;
        
        if($payType == 0){ //微信支付
            $openid = $data['openid'];
            $tradeNo = $data['transaction_id'];
            $totalFee = $data['total_fee'];
        }else if($payType == 1){ //支付宝支付
            $openid = $data['buyer_id'];
            $tradeNo = $data['trade_no'];
        }
        
        $redis = new Redis();
        $model = model('ApplyAgentOrder');
        $apply = $model->findOne(['order_no' => $orderNo], ['status', 'amount','id', 'user_id', 'merchant_id', 'mobile']);
        
        if($apply['status'] != 0){
            $msg = '订单已完成';
            return true;
        }
        
        /* if(intval($apply['amount'] * 100) !== $totalFee){
         $msg = '金额不符';
         return true;
         } */
        
        $inviter = model('User')->where(['user_id' => $apply['user_id']])->value('inviter');
        
        $time = time();
        
        $walletModel = model('UserWallet');
        
        $model->startTrans();
        
        try {
            $wallet = $walletModel->where(['user_id' => $apply['merchant_id']])->field(['agent_amount', 'amount'])->lock(true)->find();
            if(empty($wallet)) {
                $model->rollback();
                $msg = '查wallet失败';
                return false;
            }
            
            $rs = $model->modify(['id' => $apply['id']], ['trade_no' => $tradeNo, 'status' => 1]);
            if(!$rs){
                $model->rollback();
                $msg = '更新订单信息失败';
                return false;
            }
            
            $rs = model('Agent')->add(['user_id' => $apply['user_id'], 'merchant_id' => $apply['merchant_id'], 'mobile' => $apply['mobile'], 'create_time' => $time]);
            if(!$rs){
                $model->rollback();
                $msg = '加入Agent失败';
                return false;
            }
            
            $amount = $apply['amount'] * 0.9;
            
            $rs = $walletModel->modify(['user_id' => $apply['merchant_id']], ['agent_amount' => $amount + $wallet['agent_amount'], 'amount' => $amount + $wallet['amount']]);
            if(!$rs){
                $model->rollback();
                $msg = '加入Agent失败';
                return false;
            }
            
            $rs = model('UserFinanceLog')->add(['user_id' => $apply['merchant_id'], 'before_amount' => $wallet['amount'], 'amount' => $amount, 'type' => 5, 'related_id' => $apply['id'], 'add_time' => $time]);
            if(!$rs){
                $model->rollback();
                $msg = '加入UserFinanceLog失败';
                return false;
            }
            
            if($inviter > 0) {
                Task::async(function() use($apply) {
                    InnerCurl::reward('invite', ['id' => $apply['user_id'], 'type' => 3, 'target' => $apply['id']]);
                });
            }
            
            
            $model->commit();

        } catch (\Exception $e) {
            $msg = $e->getMessage();
            $model->rollback();
            return false;
        }
        
        return true;
    }
}



